/*
 *  jOTR - Java Off-The-Record Messaging Library
 *  Copyright (C) 2007 Markus Karnik
 *
 *  This program is free software; you can redistribute it and/or modify it 
 *  under the terms of the GNU General Public License as published by the
 *  Free Software Foundation; either version 3 of the License, 
 *  or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 *  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
 *  for more details.
 *
 *  You should have received a copy of the GNU General Public License along 
 *  with this program; if not, see <http://www.gnu.org/licenses/>.
 *  
 */

package de.karnik.libjotr;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.DSAParams;
import java.security.interfaces.DSAPrivateKey;
import java.security.interfaces.DSAPublicKey;

/**
 * This class implements the DSA key storage. It stores the DSA key for one users identification.
 * 
 * @author Markus Karnik - markus.karnik@my-design.org
 * @version 1.0
 * @since 1.0
 */
public class JotrDsaKeyStorage {


	/**
	 * The standard Q part of the DSA key.
	 */
	private static final byte[] Q = new byte[]{ ( byte )0x97, ( byte )0x60, ( byte )0x50, ( byte )0x8f, ( byte )0x15, 
												( byte )0x23, ( byte )0x0b, ( byte )0xcc, ( byte )0xb2, ( byte )0x92, 
												( byte )0xb9, ( byte )0x82, ( byte )0xa2, ( byte )0xeb, ( byte )0x84, 
												( byte )0x0b, ( byte )0xf0, ( byte )0x58, ( byte )0x1c, ( byte )0xf5 };

	/**
	 * The standard P part of the DSA key.
	 */
	private static final byte[] P = new byte[]{ ( byte )0xfd, ( byte )0x7f, ( byte )0x53, ( byte )0x81, ( byte )0x1d, 
												( byte )0x75, ( byte )0x12, ( byte )0x29, ( byte )0x52, ( byte )0xdf, 
												( byte )0x4a, ( byte )0x9c, ( byte )0x2e, ( byte )0xec, ( byte )0xe4, 
												( byte )0xe7, ( byte )0xf6, ( byte )0x11, ( byte )0xb7, ( byte )0x52, 
												( byte )0x3c, ( byte )0xef, ( byte )0x44, ( byte )0x00, ( byte )0xc3, 
												( byte )0x1e, ( byte )0x3f, ( byte )0x80, ( byte )0xb6, ( byte )0x51, 
												( byte )0x26, ( byte )0x69, ( byte )0x45, ( byte )0x5d, ( byte )0x40, 
												( byte )0x22, ( byte )0x51, ( byte )0xfb, ( byte )0x59, ( byte )0x3d, 
												( byte )0x8d, ( byte )0x58, ( byte )0xfa, ( byte )0xbf, ( byte )0xc5, 
												( byte )0xf5, ( byte )0xba, ( byte )0x30, ( byte )0xf6, ( byte )0xcb, 
												( byte )0x9b, ( byte )0x55, ( byte )0x6c, ( byte )0xd7, ( byte )0x81, 
												( byte )0x3b, ( byte )0x80, ( byte )0x1d, ( byte )0x34, ( byte )0x6f, 
												( byte )0xf2, ( byte )0x66, ( byte )0x60, ( byte )0xb7, ( byte )0x6b, 
												( byte )0x99, ( byte )0x50, ( byte )0xa5, ( byte )0xa4, ( byte )0x9f, 
												( byte )0x9f, ( byte )0xe8, ( byte )0x04, ( byte )0x7b, ( byte )0x10, 
												( byte )0x22, ( byte )0xc2, ( byte )0x4f, ( byte )0xbb, ( byte )0xa9, 
												( byte )0xd7, ( byte )0xfe, ( byte )0xb7, ( byte )0xc6, ( byte )0x1b, 
												( byte )0xf8, ( byte )0x3b, ( byte )0x57, ( byte )0xe7, ( byte )0xc6, 
												( byte )0xa8, ( byte )0xa6, ( byte )0x15, ( byte )0x0f, ( byte )0x04, 
												( byte )0xfb, ( byte )0x83, ( byte )0xf6, ( byte )0xd3, ( byte )0xc5, 
												( byte )0x1e, ( byte )0xc3, ( byte )0x02, ( byte )0x35, ( byte )0x54, 
												( byte )0x13, ( byte )0x5a, ( byte )0x16, ( byte )0x91, ( byte )0x32, 
												( byte )0xf6, ( byte )0x75, ( byte )0xf3, ( byte )0xae, ( byte )0x2b, 
												( byte )0x61, ( byte )0xd7, ( byte )0x2a, ( byte )0xef, ( byte )0xf2, 
												( byte )0x22, ( byte )0x03, ( byte )0x19, ( byte )0x9d, ( byte )0xd1, 
												( byte )0x48, ( byte )0x01, ( byte )0xc7 };
	
	/**
	 * The standard G part of the DSA key.
	 */
	private static final byte[] G = new byte[]{ ( byte )0xf7, ( byte )0xe1, ( byte )0xa0, ( byte )0x85, ( byte )0xd6, 
												( byte )0x9b, ( byte )0x3d, ( byte )0xde, ( byte )0xcb, ( byte )0xbc, 
												( byte )0xab, ( byte )0x5c, ( byte )0x36, ( byte )0xb8, ( byte )0x57, 
												( byte )0xb9, ( byte )0x79, ( byte )0x94, ( byte )0xaf, ( byte )0xbb, 
												( byte )0xfa, ( byte )0x3a, ( byte )0xea, ( byte )0x82, ( byte )0xf9, 
												( byte )0x57, ( byte )0x4c, ( byte )0x0b, ( byte )0x3d, ( byte )0x07, 
												( byte )0x82, ( byte )0x67, ( byte )0x51, ( byte )0x59, ( byte )0x57, 
												( byte )0x8e, ( byte )0xba, ( byte )0xd4, ( byte )0x59, ( byte )0x4f, 
												( byte )0xe6, ( byte )0x71, ( byte )0x07, ( byte )0x10, ( byte )0x81, 
												( byte )0x80, ( byte )0xb4, ( byte )0x49, ( byte )0x16, ( byte )0x71, 
												( byte )0x23, ( byte )0xe8, ( byte )0x4c, ( byte )0x28, ( byte )0x16, 
												( byte )0x13, ( byte )0xb7, ( byte )0xcf, ( byte )0x09, ( byte )0x32, 
												( byte )0x8c, ( byte )0xc8, ( byte )0xa6, ( byte )0xe1, ( byte )0x3c, 
												( byte )0x16, ( byte )0x7a, ( byte )0x8b, ( byte )0x54, ( byte )0x7c, 
												( byte )0x8d, ( byte )0x28, ( byte )0xe0, ( byte )0xa3, ( byte )0xae, 
												( byte )0x1e, ( byte )0x2b, ( byte )0xb3, ( byte )0xa6, ( byte )0x75, 
												( byte )0x91, ( byte )0x6e, ( byte )0xa3, ( byte )0x7f, ( byte )0x0b, 
												( byte )0xfa, ( byte )0x21, ( byte )0x35, ( byte )0x62, ( byte )0xf1, 
												( byte )0xfb, ( byte )0x62, ( byte )0x7a, ( byte )0x01, ( byte )0x24, 
												( byte )0x3b, ( byte )0xcc, ( byte )0xa4, ( byte )0xf1, ( byte )0xbe, 
												( byte )0xa8, ( byte )0x51, ( byte )0x90, ( byte )0x89, ( byte )0xa8, 
												( byte )0x83, ( byte )0xdf, ( byte )0xe1, ( byte )0x5a, ( byte )0xe5, 
												( byte )0x9f, ( byte )0x06, ( byte )0x92, ( byte )0x8b, ( byte )0x66, 
												( byte )0x5e, ( byte )0x80, ( byte )0x7b, ( byte )0x55, ( byte )0x25, 
												( byte )0x64, ( byte )0x01, ( byte )0x4c, ( byte )0x3b, ( byte )0xfe, 
												( byte )0xcf, ( byte )0x49, ( byte )0x2a };

	/**
	 * The standard Y part of the DSA key.
	 */
	private static final byte[] Y = new byte[]{ ( byte )0xa1, ( byte )0x3d, ( byte )0x4f, ( byte )0x7b, ( byte )0xf6, 
												( byte )0xec, ( byte )0x54, ( byte )0x0c, ( byte )0x32, ( byte )0xb7, 
												( byte )0x8a, ( byte )0x30, ( byte )0x00, ( byte )0x34, ( byte )0x90, 
												( byte )0x44, ( byte )0x95, ( byte )0xa6, ( byte )0xcf, ( byte )0x25, 
												( byte )0x1d, ( byte )0x5f, ( byte )0xcf, ( byte )0x88, ( byte )0x15, 
												( byte )0xce, ( byte )0x86, ( byte )0x43, ( byte )0x2d, ( byte )0xd6, 
												( byte )0xfe, ( byte )0xac, ( byte )0xa1, ( byte )0xb7, ( byte )0xa9, 
												( byte )0xb9, ( byte )0xe4, ( byte )0xa6, ( byte )0x4b, ( byte )0xce, 
												( byte )0x12, ( byte )0x10, ( byte )0xbc, ( byte )0xea, ( byte )0xc6, 
												( byte )0xac, ( byte )0x56, ( byte )0xb9, ( byte )0x80, ( byte )0xae, 
												( byte )0xcd, ( byte )0x35, ( byte )0x73, ( byte )0x10, ( byte )0xf7, 
												( byte )0xea, ( byte )0x5b, ( byte )0x4d, ( byte )0xe8, ( byte )0xf1, 
												( byte )0x3e, ( byte )0x47, ( byte )0x20, ( byte )0x42, ( byte )0xdc, 
												( byte )0x55, ( byte )0x53, ( byte )0x3a, ( byte )0x85, ( byte )0x80, 
												( byte )0xe2, ( byte )0xf8, ( byte )0x6e, ( byte )0x8c, ( byte )0x1f, 
												( byte )0xb4, ( byte )0x40, ( byte )0x82, ( byte )0x6f, ( byte )0xae, 
												( byte )0xea, ( byte )0x8d, ( byte )0xbb, ( byte )0xda, ( byte )0xea, 
												( byte )0xf5, ( byte )0xbc, ( byte )0x3e, ( byte )0x90, ( byte )0xcb, 
												( byte )0x41, ( byte )0x2a, ( byte )0x32, ( byte )0x9b, ( byte )0xf6, 
												( byte )0xa6, ( byte )0x7d, ( byte )0x25, ( byte )0x94, ( byte )0x4f, 
												( byte )0x4a, ( byte )0xec, ( byte )0xba, ( byte )0x3c, ( byte )0x09, 
												( byte )0xb6, ( byte )0xd9, ( byte )0xa6, ( byte )0xa7, ( byte )0x84, 
												( byte )0x65, ( byte )0x6b, ( byte )0x29, ( byte )0xe9, ( byte )0x18, 
												( byte )0x55, ( byte )0xa9, ( byte )0x49, ( byte )0xae, ( byte )0x10, 
												( byte )0xd0, ( byte )0x8e, ( byte )0xee, ( byte )0x98, ( byte )0x59, 
												( byte )0xec, ( byte )0xf6, ( byte )0x1c };
	/**
	 * The standard X part of the DSA key.
	 */
	private static final byte[] X = new byte[]{ ( byte )0x58, ( byte )0x3b, ( byte )0x79, ( byte )0x8d, ( byte )0x5f, 
												( byte )0xda, ( byte )0xa1, ( byte )0x5b, ( byte )0xa4, ( byte )0x47, 
												( byte )0xe7, ( byte )0xd4, ( byte )0xd8, ( byte )0xf9, ( byte )0x9a, 
												( byte )0x33, ( byte )0xd5, ( byte )0x58, ( byte )0x34, ( byte )0x85 };
	
	/**
	 * The local q part of the DSA key.
	 */
	private JotrMpi q = null;
	/**
	 * The local p part of the DSA key.
	 */
	private JotrMpi p = null;
	/**
	 * The local g part of the DSA key.
	 */
	private JotrMpi g = null;
	/**
	 * The local y part of the DSA key.
	 */
	private JotrMpi y = null;
	/**
	 * The local x part of the DSA key.
	 */
	private JotrMpi x = null;
	
	/**
	 * The remote q part of the DSA key.
	 */
	private JotrMpi remoteQ = null;
	/**
	 * The remote p part of the DSA key.
	 */
	private JotrMpi remoteP = null;
	/**
	 * The remote g part of the DSA key.
	 */
	private JotrMpi remoteG = null;
	/**
	 * The remote y part of the DSA key.
	 */
	private JotrMpi remoteY = null;
	
	/**
	 * Constructs a DSA key storage object with the default values.
	 */
	public JotrDsaKeyStorage() {
		q = new JotrMpi( Q );
		p = new JotrMpi( P );;
		g = new JotrMpi( G );;
		y = new JotrMpi( Y );;
		x = new JotrMpi( X );;
	}
	
	/**
	 * Creates an sets a new DSA key.
	 * 
	 * @throws NoSuchAlgorithmException
	 */
	public void generateNewKeyPair() throws NoSuchAlgorithmException {
		KeyPairGenerator gen = KeyPairGenerator.getInstance( "DSA" );
		
		gen.initialize( 1024 );
		
		KeyPair pair = gen.generateKeyPair();
		DSAPrivateKey privKey = ( DSAPrivateKey )pair.getPrivate();
		DSAPublicKey pubKey = ( DSAPublicKey )pair.getPublic();
		
		DSAParams privKeyParams = privKey.getParams();
		
		q = new JotrMpi( privKeyParams.getQ() );
		p = new JotrMpi( privKeyParams.getP() );
		g = new JotrMpi( privKeyParams.getG() );

		x  = new JotrMpi( privKey.getX() );
		y = new JotrMpi( pubKey.getY() );
	}

	/**
	 * Returns the local q part.
	 * 
	 * @return The local q part.
	 */
	public JotrMpi getQ() {
		return q;
	}

	/**
	 * Returns the local p part.
	 * 
	 * @return The local p part.
	 */
	public JotrMpi getP() {
		return p;
	}

	/**
	 * Returns the local g part.
	 * 
	 * @return The local g part.
	 */
	public JotrMpi getG() {
		return g;
	}

	/**
	 * Returns the local y part.
	 * 
	 * @return The local y part.
	 */
	public JotrMpi getY() {
		return y;
	}

	/**
	 * Returns the local x part.
	 * 
	 * @return The local x part.
	 */	
	public JotrMpi getX() {
		return x;
	}

	/**
	 *  Returns the remote q part.
	 * 
	 * @return The remote q part.
	 */
	public JotrMpi getRemoteQ() {
		return remoteQ;
	}

	/**
	 * Sets the remote q part.
	 * 
	 * @param remoteQ The remote q part to set.
	 */
	public void setRemoteQ(JotrMpi remoteQ) {
		this.remoteQ = remoteQ;
	}

	/**
	 * Returns the remote p part.
	 * 
	 * @return The remote p part.
	 */
	public JotrMpi getRemoteP() {
		return remoteP;
	}

	/**
	 * Sets the remote p part.
	 * 
	 * @param remoteP The remote p part to set.
	 */
	public void setRemoteP(JotrMpi remoteP) {
		this.remoteP = remoteP;
	}

	/**
	 * Returns the remote g part.
	 * 
	 * @return The remote g part.
	 */
	public JotrMpi getRemoteG() {
		return remoteG;
	}

	/**
	 * Sets the remote g part.
	 * 
	 * @param remoteG The remote g part to set.
	 */
	public void setRemoteG(JotrMpi remoteG) {
		this.remoteG = remoteG;
	}

	/**
	 * Returns the remote y part.
	 * 
	 * @return The remote y part.
	 */
	public JotrMpi getRemoteY() {
		return remoteY;
	}

	/**
	 * Sets the remote y part.
	 * 
	 * @param remoteY The remote y part to set.
	 */
	public void setRemoteY(JotrMpi remoteY) {
		this.remoteY = remoteY;
	}
}